#ifdef __linux__
#include <pthread.h>
#elif defined (_WIN32) || defined (WIN32) || defined (__CYGWIN__) || defined (__MINGW32__) || defined (__BORLANDC__)
#include "pthread.h"
#else
#error "OS unknow: can't load pthread lib"
#endif

#include <signal.h>
#include "libXbee.h"


pthread_t thReadID;
pthread_t thWriteID;
pthread_t thMngKbd;

unsigned int END = 0;
extern struct SCIENTIFIC_COMMANDDATA my_commanddata;
struct SCIENTIFIC_CONFIG pkgConf;

int 	angle_pitch, angle_roll, angle_yaw, av_pitch,av_roll, av_yaw, height,
	uptime,voltage,id_co_pitch,id_co_roll,id_co_yaw,id_co_thrust;

short acc_x, acc_y, acc_z,rc_chan0, rc_chan1, rc_chan2, rc_chan3, current, cpuload,
	id_raw_gyro_pitch, id_raw_gyro_roll, id_raw_gyro_yaw;

int Time_Out_Detected;

FILE *f; /* utilisé pour trace debug */

int l_getch (void) {
     static struct termios term, back;
     int ret = -1;
     tcgetattr (0, &term); //get term info
     memcpy (&back, &term, sizeof(term));
     term.c_lflag &= ~(ICANON|ECHO);    //change term attr
     term.c_cc[VTIME] = 1; //latency
     term.c_cc[VMIN] = 1; //nb char
     tcsetattr(0, TCSANOW, &term); //change stdin attr
     ret = getchar();
     tcsetattr(0, TCSANOW, &back); //restore attr
     return ret;
}

void onExit(){
	END = 1;
}

#define PITCH_STEP				40	
#define ROLL_STEP				40
#define YAW_STEP				40
#define THRUST_STEP				50

#define TIME_TO_SLEEP_READ			200000 
#define TIME_TO_SLEEP_WRITE			100000 

void *manageKbdThread(void *arg){
	int c=-1,i;
	i = (int)arg; /* suppression warning */

		fprintf(f,"%s"," Thread CLAVIER ACTIF 1\n");
	while(!END){
		c = l_getch();
		fprintf(f," Thread CLAVIER ACTIF 2 c = %d\n",c);
		switch(c)
			{
				case 0x41:/* 65 flèche haut = accélération */
					fprintf(f,"%s","fleche haut envoyee \n\n");
					add_thrust((short)THRUST_STEP);
					break;

				case 0x42:/* 66 flèche bas = décélération */
					fprintf(f,"%s","fleche bas envoyee \n\n");
					sub_thrust((short)THRUST_STEP);
					break;

				case 0x44:/* 68 flèche gauche */
					fprintf(f,"%s","fleche gauche envoyee \n\n");
					add_roll((short)ROLL_STEP);
					break;

				case 0x43:/* 67 flèche droite */
					fprintf(f,"%s","fleche droite envoyee \n\n");
					sub_roll((short)ROLL_STEP);
					break;

				case 0x34:/* touche 4 pavé numérique code 52 //100 */
					fprintf(f,"%s","touche 4 envoyee \n\n");
					add_yaw((short)YAW_STEP);
					break;

				case 0x36:/* touche 6 pavé numérique code 54 //102 */
					fprintf(f,"%s","touche 6 envoyee \n\n");
					sub_yaw((short)YAW_STEP);
					break;

				case 0x38:/* touche 8 pavé numérique code 56 //104 */
					fprintf(f,"%s","touche 8 envoyee  \n\n");
					add_pitch((short)PITCH_STEP);
					break;

				case 0x32:/* touche 2 pavé numérique code 50 //98 */
					fprintf(f,"%s","touche 2 envoyee \n\n");
					sub_pitch((short)PITCH_STEP);
					break;
#ifdef TRACEROUTE
				case 0x5A:/* touche Z */
				case 0x7A:/* touche z */
					fprintf(f,"%s","touche z envoyee traceroute appelé\n\n");
					traceroute();
#endif
					break;
			}
	}
	pthread_exit (NULL);
}


void *readThread(void *arg){
	struct SCIENTIFIC_DATA stdata;
	union scientific_packet_t rec_packet;
    	unsigned char *buffer_read;
	unsigned short flags;
	int nread = -1,i;

	acc_x = acc_y =acc_z = rc_chan0 = rc_chan1 = rc_chan2 = -1;
	angle_pitch = angle_roll = angle_yaw = av_pitch = av_roll = av_yaw = height = -1;
	uptime = voltage = current = cpuload = -1;
	id_raw_gyro_pitch = id_raw_gyro_roll = id_raw_gyro_yaw =-1;	

	/* pour supprimer warning */
	i = (int)arg;


	while(!END){

		usleep(TIME_TO_SLEEP_READ);

		bzero(&stdata,sizeof(stdata)); 

		printf("%c[H%c[2J", 0x1b, 0x1b);

		if((nread = readXBEEDev(&stdata,NULL)) == -1)
		{
			switch(xbee_error)
			{
				case XBEE_ERROR_NULL:
					break;
				case XBEE_DEV_PATH_INVALID:
					break;
				case XBEE_DEV_ALREADY_OPENED:
					break;
				case XBEE_DEV_INVALID:
					break;
				case XBEE_DEV_CANOT_OPEN:
					break;
				case XBEE_DEV_NOT_INIT:
					break;
				case XBEE_BUF_MUST_INIT:
					fprintf(f,"%s","buffer must be initialized before\n");
					break;
				case XBEE_READ_TIMEOUT_FIRED:
					fprintf(f,"%s","read timeout\n");
					break;
				case XBEE_READ_POLL_ERR:
					fprintf(f,"%s","polling error\n");
					break;
				case XBEE_READ_ERR:
					break;
				case XBEE_WRITE_TIMEOUT_FIRED:
					break;
				case XBEE_WRITE_POLL_ERR:
					break;
				case XBEE_WRITE_ERR:
					break;
			}
		}
#ifdef DEBUG
		if (xbee_error == XBEE_READ_TIMEOUT_FIRED){
			printf("j'ai eu un time out en lecture\n");
			fprintf(f,"%s","j'ai eu un time out en lecture\n");
			Time_Out_Detected = 1;
		}

		if (xbee_error == XBEE_ERROR_NULL){

			buffer_read = (unsigned char *)&stdata;


			fprintf(f,"\nbytes read = %d\n",nread);

			if ((stdata.packetdescriptor != 0) && (stdata.packetdescriptor != 5)){
				fprintf(f,"stdata.packetdescriptor  = %X\n", stdata.packetdescriptor);
			}
			else{
				fprintf(f,"stdata.packetdescriptor  = %X\n", stdata.packetdescriptor);
#if 0
				for (i=0;i<nread;i++){
				fprintf(f,"data read  = %X\n", buffer_read[i]);
				}
#endif
			}

			if ( stdata.packetdescriptor == PD_SCIENTIFICDATA)  {
				fprintf(f,"%s","\n packet is PD_SCIENTIFIC_DATA\n"); /* 0x19 */
				fprintf(f,"size of packet is %d\n",stdata.length);
			}

			if ( stdata.packetdescriptor == PD_SCIENTIFICSTATUS){
				fprintf(f,"%s","\n packet is PD_SCIENTIFICSTATUS\n") ;/*18*/
				fprintf(f,"size of packet is %d\n",nread);
			}

#endif
        	switch(*buffer_read) /* lecture du packetdescriptor */
 	       {
 	        case(PD_SCIENTIFICCOMMAND):/* 0x17 */
 	           rec_packet.cmdData = *(struct SCIENTIFIC_COMMANDDATA *)(buffer_read);
            	break;

         	case(PD_SCIENTIFICSTATUS): /* 0x18 */
            	rec_packet.statusData = *(struct SCIENTIFIC_STATUSDATA *)(buffer_read);
				bcopy(&rec_packet.statusData.flags, &flags,sizeof(flags));
#ifdef DEBUG
           	fprintf(f,"\t flags  = %x\n",flags);
		if((flags & 0x01) != 0){
			fprintf(f,"%s","Pitch control through serial interface enabled \n");
			}
		if((flags & 0x02) != 0){
			fprintf(f,"%s","Roll control through serial interface enabled \n");
			}
		if((flags & 0x04) != 0){
			fprintf(f,"%s","Thrust control through serial interface enabled \n");
			}
		if((flags & 0x08) != 0){
			fprintf(f,"%s","Yaw control through serial interface enabled \n");
			}
		if((flags & 0x10) != 0){
			fprintf(f,"%s","ACC-Mode on \n");
			}
		else
			{
			fprintf(f,"%s","ACC-Mode off \n");
			}
		if((flags & 0x20) != 0){
			fprintf(f,"%s","Height control - on (only with ACC) \n");
			}
		else
			{
			fprintf(f,"%s","Height control - off (only with ACC) \n");
			}
		if((flags & 0x80) != 0){
			fprintf(f,"%s","Scientific interface enabled by remote - control through serial link \n");
			}
		else{
			fprintf(f,"%s","Scientific interface desabled by remote - control through RC \n");
			}
	
			fprintf(f,"Actual frequency request = %d Hz \n",((flags & 0xff00)>>8)*5);

#endif
    	        break;

    	     case(PD_SCIENTIFICDATA):       /* 0x19 */
    	        rec_packet.data = *(struct SCIENTIFIC_DATA *)(buffer_read);
	
    	        bcopy(rec_packet.data.data,   &angle_pitch,sizeof(angle_pitch));
    	        bcopy(rec_packet.data.data+4, &angle_roll, sizeof(angle_roll));
    	        bcopy(rec_packet.data.data+8, &angle_yaw,  sizeof(angle_yaw));
    	        bcopy(rec_packet.data.data+12,&av_pitch,   sizeof(av_pitch));
    	        bcopy(rec_packet.data.data+16,&av_roll,    sizeof(av_roll));
    	        bcopy(rec_packet.data.data+20,&av_yaw,     sizeof(av_yaw));
    	        bcopy(rec_packet.data.data+24,&acc_x,      sizeof(acc_x));
    	        bcopy(rec_packet.data.data+26,&acc_y,      sizeof(acc_y));
    	        bcopy(rec_packet.data.data+28,&acc_z,      sizeof(acc_z));
	
    	        bcopy(rec_packet.data.data+30,&height,     sizeof(height));
    	        bcopy(rec_packet.data.data+34,&rc_chan0,   sizeof(rc_chan0));
    	        bcopy(rec_packet.data.data+36,&rc_chan1,   sizeof(rc_chan1));
    	        bcopy(rec_packet.data.data+38,&rc_chan2,   sizeof(rc_chan2));
    	        bcopy(rec_packet.data.data+40,&rc_chan3,   sizeof(rc_chan3));
	

    	        bcopy(rec_packet.data.data+42,&id_raw_gyro_pitch,   sizeof(id_raw_gyro_pitch));
    	        bcopy(rec_packet.data.data+44,&id_raw_gyro_roll,   sizeof(id_raw_gyro_roll));
    	        bcopy(rec_packet.data.data+46,&id_raw_gyro_yaw,   sizeof(id_raw_gyro_yaw));
#ifdef DEBUG
    	        fprintf(f,"\t angle_pitch = %d\n",angle_pitch);
    	        fprintf(f,"\t angle_roll  = %d\n",angle_roll);
    	        fprintf(f,"\t angle_yaw  = %d\n",angle_yaw);
    	        fprintf(f,"\t av_pitch  = %d\n",av_pitch);
    	        fprintf(f,"\t av_roll  = %d\n",av_roll);
    	        fprintf(f,"\t av_yaw  = %d\n",av_yaw);
    	        fprintf(f,"\t acc_x  = %d\n",acc_x);
    	        fprintf(f,"\t acc_y  = %d\n",acc_y);
    	        fprintf(f,"\t acc_z  = %d\n",acc_z);
	
    	        fprintf(f,"\t height  = %d\n",height);
    	        fprintf(f,"\t rc_chan0  = %d\n",rc_chan0);
    	        fprintf(f,"\t rc_chan1  = %d\n",rc_chan1);
	        fprintf(f,"\t rc_chan2  = %d\n",rc_chan2);
    	        fprintf(f,"\t rc_chan3  = %d\n",rc_chan3);

    	        printf("\t rc_chan0  = %d\n",rc_chan0);
    	        printf("\t rc_chan1  = %d\n",rc_chan1);
	        printf("\t rc_chan2  = %d\n",rc_chan2);
    	        printf("\t rc_chan3  = %d\n",rc_chan3);

    	        fprintf(f,"\t id_raw_gyro_pitch  = %d\n",id_raw_gyro_pitch);
    	        fprintf(f,"\t id_raw_gyro_roll  = %d\n",id_raw_gyro_roll);
    	        fprintf(f,"\t id_raw_gyro_yaw  = %d\n",id_raw_gyro_yaw);

#endif
    	        break;

    	   	case(PD_SCIENTIFICCONFIG):/* 0x20 */
    	    	rec_packet.config = *(struct SCIENTIFIC_CONFIG *)(buffer_read);
          	break;
    	    default:
    	        break;
    	   	 	}
			//printf("%s : flags = %x \n",__FUNCTION__,stdata.flags);TODO
			}
			usleep(TIME_TO_SLEEP_READ/100);
		}
	pthread_exit (NULL);
}


int main(int argc, char **args){
    enum xbee_error_t error;
	char *dev =  NULL;
	int cpt = 0, nwrite,noctet;

	if( (f = fopen("humm.log","a+" )) == NULL) 
		fprintf(f,"%s","fichier log non ouvert \n");
	fprintf(f,"%s","fichier de trace humm.log ouvert \n");


	if(argc < 2) {
		fprintf(f,"%s","error argument\n");
		return -1;
	}

	dev = args[1];
	fprintf(f,"path of xbee device : %s\n",dev);
	error = openXBEEDev(dev);
	if(error != XBEE_ERROR_NULL){
		fprintf(f,"%s","error while openning xbee device \n");
		return -1;
	}

	/* Création thread de lecture */
	if(pthread_create(&thReadID,NULL,readThread,NULL) != 0){
		perror("pthread_create read");
		closeXBEEDev();
		return -1;
	}

	if(pthread_create(&thMngKbd,NULL,manageKbdThread,NULL) != 0){
		perror("pthread_create manageKbd");
		closeXBEEDev();
		return -1;
	}

	signal(SIGINT,onExit);

	Time_Out_Detected = 0;

	noctet = init_pkt_conf();

	my_commanddata.packetdescriptor 	= 	PD_SCIENTIFICCOMMAND ; 		/* 0x17   */;
	my_commanddata.pitch 			=  	PITCH_MIDDLE;			/* 0x07f0 */;
	my_commanddata.roll 			=  	ROLL_MIDDLE ;			/* 0x07f0 */;

	/* ATTENTION : pour démarrer les moteurs, obligatoirement yaw et thrust à zéro  */

#ifdef MODE_ESPION
	/* pour ne pas démarrer les moteurs il suffit que yaw soit différent de zéro */
	my_commanddata.yaw   	= YAW_MIDDLE; 			/* 0x0 */
#else
	my_commanddata.yaw   	= YAW_MIN; 			/* 0x0 */
#endif

	my_commanddata.thrust 	= THRUST_MIN;		/* 0x0 */

	/* 	cmddata.flags = par pas de 5Hz:c800 = 200*5Hz - 0xFF = polling mode
		2 multiplied in MSB ie 10Hz-
		THRUST_ENABLED			0x04
		YAW_ENABLED			0x08
		TRIG_SC_STAT_PKT		0x80
	*/

#ifdef MODE_ESPION
	my_commanddata.flags = ((FIVE_HZ_STEP << 1)<<8) | (YAW_ENABLED|THRUST_ENABLED); /* 0x020c */
#else
	my_commanddata.flags = ((FIVE_HZ_STEP << 1)<<8) ; /* 0x020c */
#endif

	fprintf(f,"my_commanddata.flags = %x\n",my_commanddata.flags)	;

	while(!END){
		if (Time_Out_Detected){ /* écriture configuration des données par defaut tous les 10 coups */
			if (Time_Out_Detected){		/* detection de perte de communication */
				error = closeXBEEDev(); printf("close port serie %d\n",error);
				usleep(TIME_TO_SLEEP_WRITE/100);
				error = openXBEEDev(dev);
				Time_Out_Detected = 0; printf("port série réinitialisé %d \n",error);
			}

	            fprintf(f,"%s"," envoi de la requete de configuration \n");
	            nwrite = writeXBEEDev(&pkgConf,PD_SCIENTIFICCONFIG,noctet/* sizeof(pkgConf) */,NULL);
	            fprintf(f," requete de configuration envoyée nwrite=%d  \n",nwrite);
	            usleep(TIME_TO_SLEEP_WRITE);		

		}	
		writeXBEEDev(&my_commanddata,PD_SCIENTIFICCOMMAND,sizeof(my_commanddata),NULL);

		usleep(TIME_TO_SLEEP_WRITE);		

		if(cpt++ == 10) { 	/* demarrage */
			my_commanddata.yaw   =  YAW_MIDDLE ; //0x07f0;
#ifdef MODE_ESPION
			my_commanddata.flags =((FIVE_HZ_STEP << 1)<<8)|(TRIG_SC_STAT_PKT); 
#else
			my_commanddata.flags =((FIVE_HZ_STEP << 1)<<8)|(TRIG_SC_STAT_PKT|YAW_ENABLED |\
									THRUST_ENABLED|PITCH_ENABLED|ROLL_ENABLED); 
#endif
		}
		else 

		{
#ifdef MODE_ESPION
			my_commanddata.flags = ((FIVE_HZ_STEP << 1)<<8); /* 0x020c */
#else
			my_commanddata.flags = ((FIVE_HZ_STEP << 1)<<8)| (YAW_ENABLED|\
									THRUST_ENABLED|PITCH_ENABLED|ROLL_ENABLED);  /* 0x020c */
#endif

		}

	}

#ifndef MODE_ESPION
	/* on n'envoie pas les commandes */
	stop_motors();
#endif
	/* si sortie anticipée */
	pthread_join(thReadID,NULL);
	pthread_join(thMngKbd,NULL);

	usleep(TIME_TO_SLEEP_WRITE/10);
	fprintf(f,"%s","fichier de trace fermé \n");
	fclose(f);
	closeXBEEDev();
	return 0;
}

int add_thrust(short thrust)
{
	if((THRUST_MAX - my_commanddata.thrust)<thrust){
		my_commanddata.thrust = THRUST_MAX;
	}
	else{
	my_commanddata.thrust += thrust ;
	}
#ifdef DEBUG
	fprintf(f," Commande de thrust vaut %d \n",my_commanddata.thrust);
	printf("my_commanddata.thrust vaut %d \n",my_commanddata.thrust);
#endif
	return(EXIT_SUCCESS);
}

int sub_thrust(short thrust)
{
	if(my_commanddata.thrust>thrust){
	my_commanddata.thrust -= thrust ;
	}
	else{
	my_commanddata.thrust = THRUST_MIN;
	}
#ifdef DEBUG
	fprintf(f," Commande de thrust vaut %d \n",my_commanddata.thrust);
	printf(" my_commanddata.thrust vaut %d \n",my_commanddata.thrust);
#endif
	return(EXIT_SUCCESS);
}

int add_yaw(short yaw)
{
	/* les valeurs de yaw sont lues en millieme de degre
	comprises entre 0 et 4095 en ecriture
	angle O = angle a la mise sous tension 		*/

if(my_commanddata.yaw != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.yaw = (my_commanddata.yaw + yaw) % YAW_MAX ;
	}
#ifdef DEBUG
	fprintf(f," Commande de yaw vaut %d \n",my_commanddata.yaw);
	printf(" my_commanddata.yaw vaut %d \n",my_commanddata.yaw);
#endif
	return(EXIT_SUCCESS);
}

int sub_yaw(short yaw)
{
if(my_commanddata.yaw != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.yaw = (my_commanddata.yaw - yaw) % YAW_MAX;
	}
#ifdef DEBUG
	fprintf(f," Commande de yaw vaut %d \n",my_commanddata.yaw);
	printf(" my_commanddata.yaw vaut %d \n",my_commanddata.yaw);
#endif
	return(EXIT_SUCCESS);
}

int add_pitch(short pitch)
{
	/* les valeurs de pitch sont lues en millieme de degre
	comprises entre 0 et 4095 en ecriture

	angle O = angle a la mise sous tension 		*/

if(my_commanddata.pitch != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.pitch = (my_commanddata.pitch + pitch) % PITCH_MAX ;
	}
#ifdef DEBUG
	fprintf(f," Commande de pitch vaut %d \n",my_commanddata.pitch);
	printf(" my_commanddata.pitch vaut %d \n",my_commanddata.pitch);
#endif
	return(EXIT_SUCCESS);
}

int sub_pitch(short pitch)
{
if(my_commanddata.pitch != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.pitch = (my_commanddata.pitch - pitch) % PITCH_MAX;
	}
#ifdef DEBUG
	fprintf(f," Commande de pitch vaut %d \n",my_commanddata.pitch);
	printf(" my_commanddata.pitch vaut %d \n",my_commanddata.pitch);
#endif
	return(EXIT_SUCCESS);
}

int add_roll(short roll)
{
	/* les valeurs de pitch sont lues en millieme de degre
	comprises entre 0 et 4095 en ecriture
	angle O = angle a la mise sous tension 		*/

if(my_commanddata.roll != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.roll = (my_commanddata.roll + roll) % ROLL_MAX ;
	}
#ifdef DEBUG
	fprintf(f," Commande de roll vaut %d \n",my_commanddata.roll);
	printf(" my_commanddata.roll vaut %d \n",my_commanddata.roll);
#endif
	return(EXIT_SUCCESS);
}

int sub_roll(short roll)
{

if(my_commanddata.roll != 0)
	{/* limite les valeurs nulles aléatoires */
	my_commanddata.roll = (my_commanddata.roll - roll) % ROLL_MAX;
	}
#ifdef DEBUG
	fprintf(f," Commande de roll vaut %d \n",my_commanddata.roll);
	printf(" my_commanddata.roll vaut %d \n",my_commanddata.roll);
#endif
	return(EXIT_SUCCESS);
}

int stop_motors()
{
	
        writeXBEEDev(&pkgConf,PD_SCIENTIFICCONFIG,sizeof(pkgConf) ,NULL);

	my_commanddata.thrust   =  THRUST_MIN; 
	my_commanddata.yaw   	=  YAW_MIN;
	my_commanddata.flags 	= ((FIVE_HZ_STEP << 2)<<8)| (YAW_ENABLED|THRUST_ENABLED); /* 0x040c */



	writeXBEEDev(&my_commanddata,PD_SCIENTIFICCOMMAND,sizeof(my_commanddata),NULL);
	usleep((3*TIME_TO_SLEEP_WRITE)/10);

	my_commanddata.thrust   =  THRUST_MIN; 
	my_commanddata.yaw   =  YAW_MIN; 
	my_commanddata.flags = ((FIVE_HZ_STEP << 2)<<8)| (YAW_ENABLED|THRUST_ENABLED); /* 0x040c */

	writeXBEEDev(&my_commanddata,PD_SCIENTIFICCOMMAND,sizeof(my_commanddata),NULL);
	usleep((3*TIME_TO_SLEEP_WRITE)/10);

	my_commanddata.thrust   =  THRUST_MIN; 
	my_commanddata.yaw   =  YAW_MIN; 
	my_commanddata.flags = ((FIVE_HZ_STEP << 2)<<8)| (YAW_ENABLED|THRUST_ENABLED); /* 0x040c */

	writeXBEEDev(&my_commanddata,PD_SCIENTIFICCOMMAND,sizeof(my_commanddata),NULL);
	usleep((3*TIME_TO_SLEEP_WRITE)/10);
	return(EXIT_SUCCESS);

}

int init_pkt_conf()
{	
int noct;

	/* initialisation structure de configuration */
	noct = 0;
	bzero(&pkgConf, sizeof(pkgConf));

	//configure pkgConf for requesting data needed
	pkgConf.packetdescriptor    = 0x20;
	pkgConf.data_select[noct++] = ID_ANGLE_PITCH;	//4
	pkgConf.data_select[noct++] = ID_ANGLE_ROLL;	//4
	pkgConf.data_select[noct++] = ID_ANGLE_YAW;		//4
	pkgConf.data_select[noct++] = ID_AV_PITCH;		//4
	pkgConf.data_select[noct++] = ID_AV_ROLL;		//4
	pkgConf.data_select[noct++] = ID_AV_YAW;		//4
	pkgConf.data_select[noct++] = ID_ACC_X;			//2
	pkgConf.data_select[noct++] = ID_ACC_Y;			//2
	pkgConf.data_select[noct++] = ID_ACC_Z;			//2
	pkgConf.data_select[noct++] = ID_HEIGHT;		//4
	pkgConf.data_select[noct++] = ID_RC_CHAN0;		//2
	pkgConf.data_select[noct++] = ID_RC_CHAN1;		//2
	pkgConf.data_select[noct++] = ID_RC_CHAN2;		//2
	pkgConf.data_select[noct++] = ID_RC_CHAN3;		//2
	pkgConf.data_select[noct++] = ID_RAW_GYRO_PITCH;	//2
	pkgConf.data_select[noct++] = ID_RAW_GYRO_ROLL;		//2
	pkgConf.data_select[noct++] = ID_RAW_GYRO_YAW;		//2
	pkgConf.data_select[noct++] = 0xff;			//2 idem TestSoftware.exe et verif CRC16
	noct+=1;

return(noct);
	/* fin init structure de configuration */
}

